﻿using System;
using System.Web.Profile;
using System.Collections.Specialized;
using System.Configuration;
using System.Web.Configuration;
using System.Data.SqlClient;
using System.Data;

namespace Provider
{
    public class CustomProfileProvider : ProfileProvider
    {
        private string connectionString;

        public override void Initialize(string name, NameValueCollection config)
        {
            if (config == null)
                throw new ArgumentNullException("config");
            if (String.IsNullOrEmpty(name))
                name = "CustomProfileProvider";
            config["description"] = "CustomProfileProvider";
            if (string.IsNullOrEmpty(config["connectionStringName"]))
                throw new Exception("CustomProfileProvider can not find 'connectionStringName' in provider configuration");
            ConnectionStringsSection connectionStringsSection = (ConnectionStringsSection)WebConfigurationManager.GetSection("connectionStrings");
            connectionString = connectionStringsSection.ConnectionStrings[config["connectionStringName"]].ConnectionString;
            base.Initialize(name, config);
        }

        public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection properties)
        {
            SettingsPropertyValueCollection settings = new SettingsPropertyValueCollection();
            if (properties.Count == 0)
                return settings;
            string username = (string)context["UserName"];
            if (String.IsNullOrEmpty(username))
                return settings;
            foreach (SettingsProperty property in properties)
            {
                property.SerializeAs = SettingsSerializeAs.String;
                SettingsPropertyValue setting = new SettingsPropertyValue(property);
                setting.IsDirty = false;
                setting.Deserialized = true;
                setting.PropertyValue = GetPropertyValue(setting.Name, setting.Property.PropertyType.FullName, setting.Property.DefaultValue, username);
                settings.Add(setting);
            }
            return settings;
        }

        private object GetPropertyValue(string propertyName, string propertyType, object defaultValue, string username)
        {
            object value = defaultValue;
            string fieldName;
            switch (propertyName)
            {
                case "UserID":
                    fieldName = "UserID";
                    break;
                case "FullName":
                    fieldName = "FullName";
                    break;
                case "IsAdmin":
                    fieldName = "IsAdmin";
                    break;
                default:
                    return defaultValue;
            }
            try
            {
                //TODO
                using (SqlCommand command = new SqlCommand("SELECT UserID ,FirstName + ' ' + LastName AS FullName, IsAdmin AS IsAdmin FROM Security.[User] WHERE (UserName = @UserName)", new SqlConnection(connectionString)))
                {
                    command.Parameters.Add("UserName", SqlDbType.NVarChar).Value = ValidateParameter("UserName", username.ToLower(), true);
                    command.Connection.Open();
                    SqlDataReader reader = command.ExecuteReader();
                    if (reader.Read())
                        value = (reader[fieldName] == DBNull.Value ? defaultValue : reader[fieldName]);
                    command.Connection.Close();
                }
            }
            catch { }
            switch (propertyType)
            {
                case "System.Int64":
                    return Convert.ToInt64(value);
                case "System.Int32":
                    return Convert.ToInt32(value);
                case "System.String":
                    return Convert.ToString(value);
                case "System.Boolean":
                    return Convert.ToBoolean(value == ""? false:value);
                default:
                    return value;
            }
        }

        public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection properties)
        {
            return;
        }

        private static object ValidateParameter(string ParameterName, object Value, bool IsNullable)
        {
            if (Value == null && !IsNullable)
                throw new ArgumentNullException(ParameterName);
            return (Value == null ? DBNull.Value : Value);
        }
        #region Not Implemented Members
        public override int DeleteInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate)
        {
            throw new NotSupportedException();
        }

        public override int DeleteProfiles(string[] usernames)
        {
            throw new NotSupportedException();
        }

        public override int DeleteProfiles(ProfileInfoCollection profiles)
        {
            throw new NotSupportedException();
        }

        public override ProfileInfoCollection FindInactiveProfilesByUserName(ProfileAuthenticationOption authenticationOption, string usernameToMatch, DateTime userInactiveSinceDate, int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotSupportedException();
        }

        public override ProfileInfoCollection FindProfilesByUserName(ProfileAuthenticationOption authenticationOption, string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotSupportedException();
        }

        public override ProfileInfoCollection GetAllInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate, int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotSupportedException();
        }

        public override ProfileInfoCollection GetAllProfiles(ProfileAuthenticationOption authenticationOption, int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotSupportedException();
        }

        public override int GetNumberOfInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate)
        {
            throw new NotSupportedException();
        }

        public override string ApplicationName
        {
            get { throw new NotSupportedException(); }
            set { throw new NotSupportedException(); }
        }
        #endregion
    }
}